/**
 * Copyright 2015 jianglibo@gmail.com
 *
 */
package com.m3958.logcollector.config;

import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

import javax.annotation.Priority;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.web.MultipartProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.base.Strings;

/**
 * @author jianglibo@gmail.com
 *         2015年12月8日
 *
 */
@Component
@ConfigurationProperties(prefix = "myapp")
@Priority(1)
public class AppConfig implements InitializingBean {

    private static Logger logger = LoggerFactory.getLogger(AppConfig.class);

    private boolean bypasssecurity;

    private boolean formLogin;

    private String emberRoot;

    private String whlRoot = "whl";

    private Path whlRootPath;

    private MultipartCfg multipart;

    private String multipartLocation;

    private long multipartMaxFileSize;

    private long multipartMaxRequestSize;

    private long multipartFileSizeThreshold;

    private String qqAppId;

    private String qqAppSecret;

    private String loginEntryPoint;

    private String outSideBaseUrl;

    private String initUserName;

    private String initUserPassword;
    
    private String logoutSuccessUrl = "/";

    private boolean emailNeedVerified;

    @JsonIgnore
    private Path uploadDestFolder;

    private boolean noneDemoData = false;

    private String appHost;

    private String version;

    private final ObjectMapper objectMapper;

    @Autowired
    public AppConfig(ObjectMapper objectMapper) {
        this.objectMapper = objectMapper;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        Assert.notNull(getOutSideBaseUrl(), "please add item 'out-side-base-url' below 'appmisc' in application.yaml");

        if (getMultipartLocation() == null || getMultipartLocation().trim().isEmpty()) {
            uploadDestFolder = Paths.get(System.getProperty("java.io.tmpdir"));
        } else {
            uploadDestFolder = Paths.get(getMultipartLocation());
        }

        if (logger.isDebugEnabled()) {
            logger.debug("appmisc config is: {}", objectMapper.writeValueAsString(this));
        }

        String whlr = getWhlRoot();
        if (Strings.isNullOrEmpty(whlr)) {
            whlr = "whl";
        }
        Path wp = Paths.get(whlr);

        if (!Files.exists(wp)) {
            Files.createDirectories(wp);
        }
        this.setWhlRootPath(wp);
    }

    public String getMultipartLocation() {
        return multipartLocation;
    }

    public void setMultipartLocation(String multipartLocation) {
        this.multipartLocation = multipartLocation;
    }

    public long getMultipartMaxFileSize() {
        return multipartMaxFileSize;
    }

    public void setMultipartMaxFileSize(long multipartMaxFileSize) {
        this.multipartMaxFileSize = multipartMaxFileSize;
    }

    public long getMultipartMaxRequestSize() {
        return multipartMaxRequestSize;
    }

    public void setMultipartMaxRequestSize(long multipartMaxRequestSize) {
        this.multipartMaxRequestSize = multipartMaxRequestSize;
    }

    public long getMultipartFileSizeThreshold() {
        return multipartFileSizeThreshold;
    }

    public void setMultipartFileSizeThreshold(long multipartFileSizeThreshold) {
        this.multipartFileSizeThreshold = multipartFileSizeThreshold;
    }

    private long parseSize(String size) {
        size = size.toUpperCase();
        if (size.endsWith("KB")) {
            return Long.valueOf(size.substring(0, size.length() - 2)) * 1024;
        }
        if (size.endsWith("MB")) {
            return Long.valueOf(size.substring(0, size.length() - 2)) * 1024 * 1024;
        }
        if (size.endsWith("K")) {
            return Long.valueOf(size.substring(0, size.length() - 1)) * 1024;
        }

        if (size.endsWith("M")) {
            return Long.valueOf(size.substring(0, size.length() - 1)) * 1024 * 1024;
        }
        return Long.valueOf(size);
    }

    public boolean isBypasssecurity() {
        return bypasssecurity;
    }

    public void setBypasssecurity(boolean bypasssecurity) {
        this.bypasssecurity = bypasssecurity;
    }

    public boolean isFormLogin() {
        return formLogin;
    }

    public void setFormLogin(boolean formLogin) {
        this.formLogin = formLogin;
    }

    public MultipartCfg getMultipart() {
        return multipart;
    }

    public void setMultipart(MultipartCfg multipart) {
        this.multipart = multipart;
    }

    public Path getUploadDestFolder() {
        return uploadDestFolder;
    }

    public void setUploadDestFolder(Path uploadDestFolder) {
        this.uploadDestFolder = uploadDestFolder;
    }

    public boolean isNoneDemoData() {
        return noneDemoData;
    }

    public void setNoneDemoData(boolean noneDemoData) {
        this.noneDemoData = noneDemoData;
    }

    public String getAppHost() {
        return appHost;
    }

    public void setAppHost(String appHost) {
        this.appHost = appHost;
    }

    public String getVersion() {
        return version;
    }

    public void setVersion(String version) {
        this.version = version;
    }

    public String getLoginEntryPoint() {
        return loginEntryPoint;
    }

    public void setLoginEntryPoint(String loginEntryPoint) {
        this.loginEntryPoint = loginEntryPoint;
    }

    public String getOutSideBaseUrl() {
        return outSideBaseUrl;
    }

    public void setOutSideBaseUrl(String outSideBaseUrl) {
        this.outSideBaseUrl = outSideBaseUrl;
    }

    public String getQqAppId() {
        return qqAppId;
    }

    public void setQqAppId(String qqAppId) {
        this.qqAppId = qqAppId;
    }

    public String getQqAppSecret() {
        return qqAppSecret;
    }

    public void setQqAppSecret(String qqAppSecret) {
        this.qqAppSecret = qqAppSecret;
    }

    public String getInitUserName() {
        return initUserName;
    }

    public void setInitUserName(String initUserName) {
        this.initUserName = initUserName;
    }

    public String getInitUserPassword() {
        return initUserPassword;
    }

    public void setInitUserPassword(String initUserPassword) {
        this.initUserPassword = initUserPassword;
    }

    public String getEmberRoot() {
        return emberRoot;
    }

    public void setEmberRoot(String emberRoot) {
        this.emberRoot = emberRoot;
    }

    public boolean isEmailNeedVerified() {
        return emailNeedVerified;
    }

    public void setEmailNeedVerified(boolean emailNeedVerified) {
        this.emailNeedVerified = emailNeedVerified;
    }

    public String getWhlRoot() {
        return whlRoot;
    }

    public void setWhlRoot(String whlRoot) {
        this.whlRoot = whlRoot;
    }

    public Path getWhlRootPath() {
        return whlRootPath;
    }

    public void setWhlRootPath(Path whlRootPath) {
        this.whlRootPath = whlRootPath;
    }

    public String getLogoutSuccessUrl() {
        return logoutSuccessUrl;
    }

    public void setLogoutSuccessUrl(String logoutSuccessUrl) {
        this.logoutSuccessUrl = logoutSuccessUrl;
    }

    /**
     * @see MultipartProperties copy from it.
     * @author jianglibo
     *
     *         2015年5月30日-下午6:30:26
     */
    public static class MultipartCfg {
        private String location;

        /**
         * Max file size. Values can use the suffixed "MB" or "KB" to indicate a Megabyte or
         * Kilobyte size.
         */
        private String maxFileSize = "1Mb";

        /**
         * Max request size. Values can use the suffixed "MB" or "KB" to indicate a Megabyte
         * or Kilobyte size.
         */
        private String maxRequestSize = "10Mb";

        /**
         * Threshold after which files will be written to disk. Values can use the suffixed
         * "MB" or "KB" to indicate a Megabyte or Kilobyte size.
         */
        private String fileSizeThreshold = "0";

        public String getLocation() {
            return location;
        }

        public void setLocation(String location) {
            this.location = location;
        }

        public String getMaxFileSize() {
            return maxFileSize;
        }

        public void setMaxFileSize(String maxFileSize) {
            this.maxFileSize = maxFileSize;
        }

        public String getMaxRequestSize() {
            return maxRequestSize;
        }

        public void setMaxRequestSize(String maxRequestSize) {
            this.maxRequestSize = maxRequestSize;
        }

        public String getFileSizeThreshold() {
            return fileSizeThreshold;
        }

        public void setFileSizeThreshold(String fileSizeThreshold) {
            this.fileSizeThreshold = fileSizeThreshold;
        }
    }
}
